/**
 * @(#)Grid.jsx 0.5.1 2017-09-13
 * Copyright (c) 2017, YUNXI. All rights reserved.
 * YUNXI PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */
import React from 'react'
import { Table, Row, Col, Input, Popconfirm, Select, Form, DatePicker, TreeSelect, Cascader, InputNumber } from 'antd'
import { cloneDeep, isEmpty, get } from 'lodash';
import cx from 'classnames'
import { connect } from 'dva'
import styles from './Grid.less'
import moment from 'moment';
import _ from 'lodash'
import { setLocalData } from '../../utils/globalScope'
import config from '../../config/config'
import { arrFilter, sortListBy } from '../../utils/util'

const { RangePicker, MonthPicker } = DatePicker;
const FormItem = Form.Item;
const Option = Select.Option;
const formItemLayout = {
  labelCol: {
    xs: { span: 10 },
    sm: { span: 10 },
  },
  wrapperCol: {
    xs: { span: 14 },
    sm: { span: 14 },
  },
};
const bigFormItemLayout = {
  labelCol: {
    xs: { span: 4 },
    sm: { span: 4 },
  },
  wrapperCol: {
    xs: { span: 10 },
    sm: { span: 10 },
  },
};


/*
 * 动态生成搜索框组件
 *
 * @author 苏离
 * @since 0.5.1
 */
export const QueryCondition = ({ data, inputChange,ColStyle }) => {
  function disabledDate(type, value, item) {
    let result = false;
    if (isEmpty(item)) {
      result = false;
    } else {
      if (type === 'start') {
        //如果是开始时间，需要校验结束时间
        if (item[1]) {
          result = value.startOf('month').valueOf() >= moment(item[1]).valueOf()
        }
      } else {
        //如果是结束时间，需要校验开始时间
        if (item[0]) {
          result = value.startOf('month').valueOf() <= moment(item[0]).valueOf()
        }
      }
    }

    return result;
  }
  let list = [];
  if (!isEmpty(data)) {
    list = data.map((item, index) => {
      let cascaderList = cloneDeep(item.list);
      //item.type === 'cascader' && cascaderList.unshift({ label: '请选择', value: 'all', key: 'all' });

      if (item.type === 'date') {
        let searchCol =  {
          xs: { span: 24 },
          md: { span: 24 },
          lg: { span: 16 },
          xl: { span: 10 }
        }
        let searchFormItem = { labelCol: { span: 6 }, wrapperCol: { span: 18 } };

        return <Col {...searchCol} key={`Col-${index}`}>
          <Input type='hidden' />
          <FormItem {...searchFormItem} label={item.name} className={cx(styles.inputComponent, styles.rangePicker)}>
            {item.type === 'date' && <RangePicker style={{ width: '100%' }} allowClear={false}
              showTime={{ format: 'HH:mm' }} format="YYYY-MM-DD HH:mm" placeholder={['开始时间', '结束时间']}
              ranges={config.rangePickerRanges}
              onChange={(dates, dateStrings) => inputChange(item.key, dateStrings)}
              value={!isEmpty(item.value) ? [moment(item.value[0]), moment(item.value[1])] : []} {...(item.options ? item.options : {})} />
            }
          </FormItem>
        </Col>
      }
      ColStyle=ColStyle?ColStyle:{
          xs: { span: 24 },
          md: { span: 24 },
          lg: { span: 12 },
          xl: { span: 8 }
      }
      return <Col {...ColStyle} key={`Col-${index}`}>
        <FormItem {...formItemLayout} label={item.name} className={cx(styles.inputComponent)}>
          <Input type='hidden' />
          {item.type === 'time' && <RangePicker style={{ width: '100%' }} allowClear={false}
            onChange={(dates, dateStrings) => inputChange(item.key, dateStrings)}
            ranges={config.rangePickerRanges}
            value={!isEmpty(item.value) ? [moment(item.value[0]), moment(item.value[1])] : []} />
          }
          {item.type === 'date' && <RangePicker style={{ width: '100%' }} allowClear={false}
            showTime={{ format: 'HH:mm' }} format="YYYY-MM-DD HH:mm" placeholder={['开始时间', '结束时间']}
            ranges={config.rangePickerRanges}
            onChange={(dates, dateStrings) => inputChange(item.key, dateStrings)}
            value={!isEmpty(item.value) ? [moment(item.value[0]), moment(item.value[1])] : []} />
          }
          {item.type === 'monthOne' && <span>
            <MonthPicker placeholder="开始日期" onChange={(dates, dateString) => {
              let value = item.value;
              value
                ? value[0] = dateString
                : value = [dateString];
              inputChange(item.key, value)
            }} disabledDate={(v) => disabledDate('start', v, item.value)} value={!isEmpty(item.value[0]) ? moment(item.value[0]) : null} format="YYYY-MM" />
            </span> 
          }
          {item.type === 'month' && <span>
            <MonthPicker style={{ width: '47%', marginRight: 0 }} placeholder="开始日期" onChange={(dates, dateString) => {
              let value = item.value;
              value
                ? value[0] = dateString
                : value = [dateString];
              inputChange(item.key, value)
            }} disabledDate={(v) => disabledDate('start', v, item.value)} value={!isEmpty(item.value[0]) ? moment(item.value[0]) : null} format="YYYY-MM" />
            <span className={cx(styles.monthSpliter)}>-</span>
            <MonthPicker placeholder="结束日期" style={{ width: '47%', marginRight: 0 }} onChange={(dates, dateString) => {
              let value = item.value;
              value
                ? value[1] = dateString
                : value = [null, dateString];
              inputChange(item.key, value)
            }} disabledDate={(v) => disabledDate('end', v, item.value)} value={!isEmpty(item.value[1]) ? moment(item.value[1]) : null} format="YYYY-MM" />
          </span>
          }
          {
            item.type === 'select' &&
            <Select value={item.value ? item.value + '' : (item.notNeedAll ? '' : 'all')} placeholder={'请选择' + item.name}
              onChange={v => inputChange(item.key, v === 'all' ? '' : v)}>
              {item.notNeedAll || <Option value={'all'}>请选择</Option>}
              {
                item.list.length&&item.list.map((d, i) => {
                  return <Option key={`${item.key}${i}`} value={d.id + ''}>{d.name}</Option>
                })
              }
            </Select>
          }
          {
            item.type === 'selectClear' &&
            <Select value={item.value ? item.value + '' : (item.notNeedAll ? '' : 'all')} placeholder={'请选择' + item.name}
              onChange={v => inputChange(item.key, v)} allowClear={item.allowClear?item.allowClear:false}>
              {/* {item.notNeedAll || <Option value={'all'}>请选择</Option>} */}
              {
                item.list.length&&item.list.map((d, i) => {
                  return <Option key={`${item.key}${i}`} value={d.id + ''}>{d.name}</Option>
                })
              }
            </Select>
          }
          {
            item.type === 'selectsSarch' &&
            <Select value={item.value ? item.value + '' : (item.notNeedAll ? '' : 'all')} placeholder={'请选择' + item.name}
              onChange={v => inputChange(item.key, v === 'all' ? '' : v)} allowClear={true} showSearch={true}>
              {item.notNeedAll || <Option value={'all'}>请选择</Option>}
              {
                item.list.length&&item.list.map((d, i) => {
                  return <Option key={`${item.key}${i}`} value={d.name + ''}>{d.name}</Option>
                })
              }
            </Select>
          }
          {
            item.type === 'comboSelect' &&
            <Select  mode="combobox" value={item.value ? item.value + '' : ''} filterOption={(inputValue, option) => {
              return option.props.searchValue.includes(inputValue)
            }} placeholder={item.placeholder || '请输入' + item.name}
              onSelect={(v) => {
                let newV = v.split(' '), vName = '';
                if (newV[1]) {
                  newV.forEach((vItem, vIdx) => {
                    if (vIdx !== 0) {
                      if (!vName) {
                        vName = vItem;
                      } else {
                        vName += (' ' + vItem);
                      }

                    }
                  })

                } else {
                  vName = v;
                }
                // inputChange(item.key, v.split(' ')[1] || v, v)
                inputChange(item.key, vName, v)
              }}
              onSearch={v => inputChange(item.key, v)}
              {...item.option}>
              {
                item.list.map((d, i) => {
                  let value = item.isUniqueName ? d.name : (d.id + ' ' + d.name);
                  let name = item.isUniqueName ? d.name : (d.id + ' ' + d.name);
                  return <Option searchValue={d.searchValue} key={`${item.key}${i}`} value={value}>{name}</Option>
                })
              }
            </Select>
          }
          {
            item.type === 'mulSelect' &&
            <Select value={item.value || []} placeholder={'请选择' + item.name} mode="multiple"
              onChange={v => inputChange(item.key, v)}  filterOption={true} optionFilterProp="children">
              {
                item.list.map((d, i) => {
                  return <Option key={`${item.key}${i}`} value={d.id + ''}>{d.name}</Option>
                })
              }
            </Select>
          }
          {
            item.type === 'text' &&
            <Input onChange={e => e.target.value.length < 36 && inputChange(item.key, _.trim(e.currentTarget.value))}
              value={item.value}
              placeholder={item.placeholder ? item.placeholder : '请输入' + item.name}
            />
          }
          {
            (item.reload&&item.type === 'treeSelect') &&
            <TreeSelect value={item.value ? item.value + '' : null} dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
              treeCheckStrictly
              treeData={item.list} placeholder={'请选择' + item.name}
              onChange={v => inputChange(item.key, v)}
              treeDefaultExpandAll
              
              />
          }
          {
            (!item.reload&&item.type === 'treeSelect') &&
            <TreeSelect value={item.value ? item.value + '' : null} dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
              treeCheckStrictly
              treeData={item.list} placeholder={'请选择' + item.name}
              onChange={v => inputChange(item.key, v)}
              treeDefaultExpandAll
              />
          }
          {
            item.type === 'cascader' &&
            <Cascader style={{ width: '100%' }} value={item.value ? item.value : ['all']} placeholder={'请选择' + item.name} options={cascaderList}
              onChange={(v) => { return inputChange(item.key, v) }} changeOnSelect />
          }
          {
            item.type === 'numRange' && <span>
              <InputNumber min={0} precision={item.precision ? item.precision : 0} style={{ width: 80, marginRight: 0 }} onChange={v => {
                item.value[0] = v;
                inputChange(item.key, item.value, 0)
              }} value={(item.value && item.value[0] !== undefined && item.value[0] !== null) ? item.value[0] : ''} />
              <span className="mgl2 mgr2">~</span>
              <InputNumber min={0} precision={item.precision ? item.precision : 0} style={{ width: 80, marginRight: 0 }} onChange={v => {
                item.value[1] = v;
                inputChange(item.key, item.value)
              }} value={(item.value && item.value[1] !== undefined && item.value[1] !== null) ? item.value[1] : ''} />
            </span>
          }
          {
            item.after
          }
        </FormItem>
      </Col>;
    })
  }
  return <Row>
    {list}
  </Row>;
};

//分页控件
const pagination = ({ pageChange, total=0, pageConfig, nameSpace, dispatch }) => {
  let pageChangeEvent;
  //当前路径
  const path = location.hash.split('?')[0].slice(1);
  if (!(typeof pageChange === 'function')) {
    pageChangeEvent = (pageNo, pageSize) => dispatch({
      type: `${nameSpace}/${pageChange}`,
      payload: { pageNo: pageNo, pageSize, key: 'tableData' }
    })
  } else {
    pageChangeEvent = pageChange;
  }
  setLocalData(path, pageConfig.pageSize)
  return {
    pageSize: pageConfig.pageSize,
    showTotal: total => `共 ${total} 条`,
    showQuickJumper: true,
    current: Number(pageConfig.pageNo) || 1,
    total,
    showSizeChanger: true,
    onChange: (pageNo, pageSize) => pageChangeEvent(Number(pageNo), pageSize),
    pageSizeOptions: pageConfig.pageSizeOptions || config.largePageSizeList,
    onShowSizeChange: (pageNo, pageSize) => pageChangeEvent(Number(pageNo), pageSize),
  }
};

/*
 *columns: array，对应表格头部
 *dataSource：array，表格主体内容
 *pageChange: 翻页时触发的方法
 *selectedRowKeys: 选中项的 key 数组
 *selectedKeysChange: 选中项改变时触发
 *total：分页数据总条数
 *operationIpt={[//开启表头操作项
 {
 key:'outStorageCode', //要开启表头操作项的列的key
 keyRender:"xx.xx",//如果排序字段是多重字段，将传入字段路径
 type:["filter","tdWidth","sort"],//要开启的操作项， 过滤，可变列宽，排序
 cbk:(e)=>{
 updateModel(e,'outStorageCodeSe'); //回调函数，将操作值返回回来
 },
 value:outStockListModel2.outStorageCodeSe,//存储在当前组件的操作值，默认值应该和 type项一致   如开启了三个操作  则默认值应该为 ["","",""]
 }
 ]}
 */
//通用table组件
const TableComponent = (options={}) => {
  let { dispatch, nameSpace, data, selectedKeysChange, onChange, pageChange, operationIpt = [], conditionLine = 1,
    scroll = { x: 1500 }, loading, disableVerify, paginationFlag = true, isDisplayOrder = false, footer }=options
  
  const { columns, tableData, selectedRowKeys, pageConfig } = data;
  const { total=0, dataSource } = tableData;
  const rowSelection = {
    selectedRowKeys,
    onChange: (selectedRowKeys, selectedRows) => {
      dispatch({ type: `${nameSpace}/${selectedKeysChange}`, payload: { selectedRowKeys,selectedRows } })
    },
    getCheckboxProps: record => ({
      disabled: disableVerify ? disableVerify(record) : false,
    })
  };
  !isEmpty(dataSource) && dataSource.forEach((item, index) => {
    isEmpty(item.key) && (item.key = item.id || index);
  })
  //查询条件行的高度
  const queryLine = 52;

  const { pageNo=1, pageSize=0 } = pageConfig;
  let copyColumns = cloneDeep(columns);
  isDisplayOrder && copyColumns.unshift({
    title: '序号', 
    width: 60,
    dataIndex: 'commonOrder',
    key: 'commonOrder',
    render: (data, record, index) => (pageNo - 1) * pageSize + index + 1
  })
  {/* 增加行样式 */ }
  //如果有开启过滤项
  let sourceData = cloneDeep(dataSource);
  const formItemLayout3 = {
    labelCol: { span: 7 },
    wrapperCol: { span: 17 },
  }

  //替换数组中某个值
  //原始数组，数组中的目标标识字段，要替换的字段，要替换的值
  const arrReplace = function (ar, field, replaceid, val) {
    ar.map((item, idx) => {
      if (item.key == field) {
        ar[idx][replaceid] = val;
      }
    });
    return ar;
  }

  if (operationIpt.length > 0) {
    copyColumns.map((item) => {
      operationIpt.map((item2) => {
        if (item.key == item2.key) {
          let optHtml = [];
          //过滤
          item2.type.map((item3, idx) => {
            if (item3 == 'filter') {
              //合并搜索值
              sourceData = arrFilter(sourceData, item2.keyRender || item2.key, item2.value[idx]);
              optHtml.push(<FormItem {...formItemLayout3} label="筛选">
                <Input
                  placeholder="请输入筛选信息"
                  value={item2.value[idx]}
                  onChange={(e) => {
                    //将值插入到外部值数组相应的位置
                    item2.value[idx] = e.target.value;
                    item2.cbk(item2.value);
                  }}
                />
              </FormItem>)
            } else if (item3 == 'tdWidth') {
              //合并列宽值
              item2.value[idx] > 0 ? copyColumns = arrReplace(copyColumns, item2.key, "width", item2.value[idx]) : "";
              optHtml.push(<FormItem {...formItemLayout3} label="列宽">
                <Input
                  placeholder="请输入列宽（px）"
                  value={item2.value[idx]}
                  onChange={(e) => {
                    //将值插入到外部值数组相应的位置
                    item2.value[idx] = e.target.value;
                    item2.cbk(item2.value);
                  }}
                />
              </FormItem>)
            } else if (item3 == 'sort') {
              //排序
              copyColumns = arrReplace(copyColumns, item2.key, "sorter", true);
              onChange = function (a, b, c) {
                let val = cloneDeep(item2.value);
                if (c.field) {
                  let currentInfo = arrFilter(operationIpt, "key", c.field)[0];//当前操作的数据
                  val[idx] = c.order;
                  currentInfo.cbk(val);
                }
              }
              sourceData = sortListBy(sourceData, item.key, item2.value[idx]);
            }
          })
          item.filterDropdown = optHtml.length ? (
            <div className="custom-filter-dropdown">
              {optHtml}
            </div>
          ) : false
        }
      });

    });
  }

  return <Table
    columns={copyColumns}
    onChange={onChange}
    rowClassName={(record, index) => record['orderStatus'] == 1 ? (styles.bg2 + ' bg2') : ''}
    className={cx(styles.textNoWrap, styles.table)}
    rowSelection={selectedRowKeys ? rowSelection : null}
    dataSource={sourceData} loading={loading} scroll={{ ...scroll, y: (!isEmpty(dataSource) && dataSource.length > 15) ? 500 : '' }}
    pagination={paginationFlag ? pagination({ pageChange, nameSpace, total, pageConfig, dispatch }) : false}
    footer={footer ? () => footer : undefined} />;
};

//导出可编辑表格、通用表格
export const Grid = connect()(TableComponent);
